<?php

/**
 * Shopalong navigation history class
 *
 * Copyright (c) 2003 osCommerce
 * Portions Copyright (c) 2006 Shopalong
 *
 * @license http://opensource.org/licenses/gpl-license.php GNU Public License
 */

class NavigationHistory
{
	var $_path;
	var $_snapshot;
	
	/**
	 * Constructor function
	 *
	 * @access public
	 */
	
	function NavigationHistory()
	{
		global $sessionnavigation, $session;
		
		if ($session->isRegistered('navigation') && is_object($navigation))
		{
			if (PHP_VERSION < 4)
			{
				$brokenNavigation = $sessionnavigation;
				$this->_unserialize($brokenNavigation);
				$sessionnavigation = $this;
			}
			
			else
			{
				// PHP5 doesn't seem to allow re-assignment of $this, so we need
				// to map object variables of $sessionnavigation to $this
				// $this = $sessionnavigation;
				$mapVars = get_class_vars('NavigationHistory');
				
				foreach($mapVars AS $key=>$value) {
					$this->$key = &$sessionnavigation->$key;
				}
			}
		}
		
		// or create a new one if it doesn't exist
		else
		{
			$session->register('navigation');
			$this->_reset();
			$sessionnavigation = $this;
		}
	}
	
	/**
	 * Add the current page to the navigation path
	 *
	 * @access public
	 */
	
	function addCurrentPage()
	{
		global $PHP_SELF, $HTTP_GET_VARS, $HTTP_POST_VARS, $request_type, $cPath, $sessionnavigation;
		
		$set = 'true';
		
		for ($i=0, $n=sizeof($this->_path); $i<$n; $i++)
		{
			if ( ($this->_path[$i]['page'] == basename($PHP_SELF)) )
			{
				if (isset($cPath))
				{
					if (!isset($this->_path[$i]['get']['cPath']))
					{
						continue;
					}
					
					else
					{
						if ($this->_path[$i]['get']['cPath'] == $cPath)
						{
							array_splice($this->_path, ($i+1));
							$set = 'false';
							break;
						}
						
						else
						{
							$old_cPath = explode('_', $this->_path[$i]['get']['cPath']);
							$new_cPath = explode('_', $cPath);
							
							for ($j=0, $n2=sizeof($old_cPath); $j<$n2; $j++)
							{
								if ($old_cPath[$j] != $new_cPath[$j])
								{
									array_splice($this->_path, ($i));
									$set = 'true';
									break 2;
								}
							}
						}
					}
				}
				
				else
				{
					array_splice($this->_path, ($i));
					$set = 'true';
					break;
				}
			}
		}
		
		if ($set == 'true')
		{
			$this->_path[] = array
			(
				'page' => basename($PHP_SELF),
				'mode' => $request_type,
				'get' => $HTTP_GET_VARS,
				'post' => $HTTP_POST_VARS
			);
		}
		
		$sessionnavigation = $this;
	}
	
	/**
	 * Clears the navigation snapshot
	 *
	 * @access public
	 */
	
	function clearSnapshot()
	{
		global $sessionnavigation;
		$this->_snapshot = array();
		$sessionnavigation = $this;
	}
	
	/**
	 * Get an item in the navigation history
	 *
	 * @access public
	 * @param integer $history The number of items back in the history to get (default 0 - most recent item)
	 * @return array The snapshot item
	 */
	
	function getSnapshotItem($history=0)
	{
		$index = $this->getSnapshotSize() - $history;
		return $this->_snapshot($index);
	}
	
	/**
	 * Get the size of the navigation history
	 *
	 * @access public
	 * @return integer
	 */
	
	function getSnapshotSize()
	{
		return sizeof($this->_snapshot);
	}
	
	/**
	 * Removes the current page from the navigation path
	 *
	 * Useful if the page is one which doesn't display content
	 *
	 * @access public
	 */
	
	function removeCurrentPage()
	{
		global $PHP_SELF, $sessionnavigation;
		
		$lastEntryPosition = sizeof($this->_path) - 1;
		
		if ($this->_path[$lastEntryPosition]['page'] == basename($PHP_SELF))
		{
			unset($this->_path[$lastEntryPosition]);
		}
		
		$sessionnavigation = $this;
	}
	
	/**
	 * Set the specified entry in the path as the navigation snapshot
	 *
	 * @access public
	 * @param integer $history The entry in history back from the latest to use
	 * for the snapshot
	 */
	
	function setPathAsSnapshot($history = 0)
	{
		$pos = (sizeof($this->_path)-1-$history);
		$this->setSnapshot($this->_path[$pos]);
	}
	
	/**
	 * Set the navigation snapshot
	 *
	 * @todo We need a more detailed description of the purpose of the snapshot
	 * and its use for developers
	 *
	 * @access public
	 * @param array $page The page information to be used for the snapshot
	 */
	
	function setSnapshot($page = '')
	{
		global $PHP_SELF, $HTTP_GET_VARS, $HTTP_POST_VARS, $request_type, $sessionnavigation;
		
		if (is_array($page))
		{
			$this->_snapshot = array
			(
				'page' => $page['page'],
				'mode' => $page['mode'],
				'get' => $page['get'],
				'post' => $page['post']
			);
		}
		
		else
		{
			$this->_snapshot = array
			(
				'page' => basename($PHP_SELF),
				'mode' => $request_type,
				'get' => $HTTP_GET_VARS,
				'post' => $HTTP_POST_VARS
			);
		}
		
		$sessionnavigation = $this;
	}
	
	/**
	 * Reset the navigation session
	 *
	 * @access private
	 */
	
	function _reset()
	{
		global $sessionnavigation;
		$this->_path = array();
		$this->_snapshot = array();
		$sessionnavigation = $this;
	}
	
	/**
	 * Unserialize the navigation
	 *
	 * @access private
	 * @param array $broken The serialized navigation to be restored
	 */
	
	function _unserialize($broken)
	{
		for(reset($broken);$kv=each($broken);)
		{
			$key=$kv['key'];
			
			if (gettype($this->$key)!='user function')
			{
				$this->$key=$kv['value'];
			}
		}
	}
}

?>
